package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterDictionaryConvertor;
import org.jupiter.blog.api.domain.JupiterDictionary;
import org.jupiter.blog.api.dto.JupiterDictionaryDTO;
import org.jupiter.blog.service.mapper.JupiterDictionaryMapper;
import org.jupiter.blog.service.service.JupiterDictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class JupiterDictionaryServiceImpl implements JupiterDictionaryService {

	@Autowired
	private JupiterDictionaryMapper dictionaryMapper;

	@Autowired
	private JupiterDictionaryConvertor dictionaryConvertor;

	@Override
	@Transactional
	public void createDictionary(JupiterDictionaryDTO dto) {
		JupiterDictionary dictionary = dictionaryConvertor.toEntity(dto);
		if (!StringUtils.hasText(dictionary.getUuid())){
			dictionary.setUuid(UUID.randomUUID().toString());
		}
		dictionary.setCreateTime(LocalDateTime.now());
		dictionary.setUpdateTime(LocalDateTime.now());
		dictionaryMapper.insert(dictionary);
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterDictionaryDTO getById(String uuid) {
		JupiterDictionary dictionary = dictionaryMapper.selectByUuid(uuid);
		return dictionaryConvertor.toDto(dictionary);
	}

	@Override
	@Transactional
	public void updateDictionary(String uuid, JupiterDictionaryDTO dto) {
		JupiterDictionary dictionary = dictionaryConvertor.toEntity(dto);
		dictionary.setUuid(uuid);
		dictionary.setUpdateTime(LocalDateTime.now());
		dictionaryMapper.updateByUuidSelective(dictionary);
	}

	@Override
	@Transactional
	public void deleteDictionary(String uuid) {
		dictionaryMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterDictionaryDTO> getByPage(JupiterDictionaryDTO queryDTO) {
		int offset = (queryDTO.getPage() - 1) * queryDTO.getSize();
		List<JupiterDictionary> dictionaries = dictionaryMapper.selectByPage(
				queryDTO.getDictType(),
				queryDTO.getDictKey(),
				queryDTO.getDictLabel(),
				offset,
				queryDTO.getSize()
		);
		return dictionaries.stream()
				.map(dictionaryConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public long getCount(JupiterDictionaryDTO queryDTO) {
		return dictionaryMapper.countByQuery(
				queryDTO.getDictType(),
				queryDTO.getDictKey(),
				queryDTO.getDictLabel()
		);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterDictionaryDTO> getAll() {
		List<JupiterDictionary> dictionaries = dictionaryMapper.selectAll();
		return dictionaries.stream()
				.map(dictionaryConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterDictionaryDTO> getByDictType(String dictType) {
		List<JupiterDictionary> dictionaries = dictionaryMapper.selectByDictType(dictType);
		return dictionaries.stream()
				.map(dictionaryConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterDictionaryDTO> getByParentUuid(String parentUuid) {
		List<JupiterDictionary> dictionaries = dictionaryMapper.selectByParentUuid(parentUuid);
		return dictionaries.stream()
				.map(dictionaryConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterDictionaryDTO getByDictTypeAndKey(String dictType, String dictKey) {
		JupiterDictionary dictionary = dictionaryMapper.selectByDictTypeAndKey(dictType, dictKey);
		return dictionaryConvertor.toDto(dictionary);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterDictionaryDTO> getActiveByDictType(String dictType) {
		List<JupiterDictionary> dictionaries = dictionaryMapper.selectActiveByDictType(dictType);
		return dictionaries.stream()
				.map(dictionaryConvertor::toDto)
				.collect(Collectors.toList());
	}
}
